package com.ujn.spu.core;

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Component
public class SerialPortManager {

    @Autowired
    WebSocketManager webSocketManager;

    //串口设备描述
    private static final String VIRTUAL_SERIAL = "ELTIMA_Virtual_Serial_Port";

    private static final int SAFETY_SLEEP_TIME = 2000;

    private static final int DEFAULT_BAUD_RATE = 9600;

    private static final int DEFAULT_DATA_BITS = 8;


    /**
     * 查询当前设备的端口名称
     */
    public List<String> getPortNames(){
        SerialPort[] ports = SerialPort.getCommPorts();
        List<String> portNames = new ArrayList<>();
        for (SerialPort port : ports) {
            if (port.getPortDescription().contains(VIRTUAL_SERIAL)){
                portNames.add(port.getSystemPortName());
            }
        }
        return portNames;
    }


    /**
     * 打开串口
     */
    public SerialPort openDevice(String portName){
        SerialPort commPort = SerialPort.getCommPort(portName);
        if (commPort.isOpen()){
            return commPort;
        }
        if (commPort.openPort()){
            //打开串口成功，设置端口参数
            commPort.setBaudRate(DEFAULT_BAUD_RATE);
            commPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
            //设置监听器
            commPort.addDataListener(new SerialPortDataListener() {
                @Override
                public int getListeningEvents() {
                    return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
                }

                @Override
                public void serialEvent(SerialPortEvent serialPortEvent) {
                    if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE){
                        return;
                    }
                    byte[] newData = new byte[commPort.bytesAvailable()];
                    int numRead = commPort.readBytes(newData, newData.length);
                    try {
                        webSocketManager.sendMessageToClient("receive: " + new String(newData, "UTF-8"));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println(commPort + "=>> Read "+ numRead + "bytes.");
                }
            });
            return commPort;
        }
        return null;
    }

    /**
     * 串口发送信息
     */
    public boolean sendMessage(SerialPort serialPort, String msg){
        byte[] msgBytes = msg.getBytes(StandardCharsets.UTF_8);

        return serialPort.writeBytes(msgBytes, msgBytes.length) != -1;
    }
}
